﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.ComponentModel;
using System.IO;

namespace PTA.Net
{
    public static class NetworkDriverHelper
    {
        #region 外部资源
        [StructLayout(LayoutKind.Sequential)]
        public class NetResource
        {
            public int dwScope = 2;
            public int dwType = 1;
            public int dwDisplayType = 3;
            public int dwUsage = 1;
            public string lpLocalName;
            public string lpRemoteName;
            public string lpComment;
            public string lpProvider;
        }
        [DllImport("mpr.dll", EntryPoint = "WNetGetConnection", CharSet = CharSet.Unicode, SetLastError = true)]
        private static extern uint WNetGetConnection([MarshalAs(UnmanagedType.LPTStr)] string localName, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder remoteName, ref int length);

        [DllImport("mpr.dll", EntryPoint = "WNetAddConnection2", CharSet = CharSet.Ansi, SetLastError = true)]
        private static extern uint WNetAddConnection2(NetResource lpNetResource, string lpPassword, string lpUsername, uint dwFlags);

        [DllImport("Mpr.dll", EntryPoint = "WNetCancelConnection2", CharSet = CharSet.Ansi, SetLastError = true)]
        private static extern uint WNetCancelConnection2(string lpName, uint dwFlags, bool fForce);
        #endregion

        /// <summary>
        /// 为远程路径创建本地驱动器映射
        /// </summary>
        /// <param name="remote">远程路径</param>
        /// <param name="user">用户名</param>
        /// <param name="pwd">密码</param>
        /// <param name="local">本地路径，如X:</param>
        /// <returns></returns>
        [Description("创建网络映射驱动器，远程路径和本地路径都不要以/结尾")]
        public static bool CreateNetworkDriver(string remote, string user, string pwd, string local)
        {
            if (!Directory.Exists(local))
            {
                remote.TrimEnd('/').TrimEnd('\\');
                local.TrimEnd('/').TrimEnd('\\');
                if (!local.EndsWith(":"))
                {
                    local += ":";
                }
                return WNetAddConnection2(new NetResource() { lpLocalName = local, lpRemoteName = remote }, pwd, user, 0).Equals(0);
            }
            return true;
        }

        [Description("移除网络映射驱动器，本地路径都不要以/结尾")]
        public static bool RemoveNetworkDriver(string local, bool force = true)
        {
            local.TrimEnd('/').TrimEnd('\\');
            if (!local.EndsWith(":"))
            {
                local += ":";
            }
            return WNetCancelConnection2(local, 0, force).Equals(0);
        }

        [Description("获取本地映射路径的原始网络路径")]
        public static string GetNetworkPath(string local)
        {
            StringBuilder remote = new StringBuilder(512);
            int size = remote.Capacity;
            if (local != null && local.Length > 2 && local[1] == ':' && ((local[0] >= 'a' && local[0] <= 'z') || (local[0] >= 'A' && local[0] <= 'Z')))
            {
                var dirver = local.Substring(0, 2);
                if (WNetGetConnection(dirver, remote, ref size).Equals(0))
                {
                    DirectoryInfo dir = new DirectoryInfo(local);
                    string path = System.IO.Path.GetFullPath(local).Substring(System.IO.Path.GetPathRoot(local).Length);
                    return System.IO.Path.Combine(remote.ToString().TrimEnd(), path);
                }
            }
            return local;
        }
    }
}
